'''Clue-less skeleton'''

import itertools
import operator

player_names = [ 'Miss Scarlet',
                 'Col. Mustard',
                 'Mrs. White',
                 'Mr. Green',
                 'Mrs. Peacock',
                 'Prof. Plum']

def make_house():

    # create rooms
    study    = Room( 'Study',         (0,0) )
    hall     = Room( 'Hall',          (0,1) )
    lounge   = Room( 'Lounge',        (0,2) )
    library  = Room( 'Library',       (1,0) )
    billiard = Room( 'Billiard Room', (1,1) )
    dining   = Room( 'Dining Room',   (1,2) )
    conserv  = Room( 'Conservatory',  (2,0) )
    ball     = Room( 'Ball Room',     (2,1) )
    kitchen  = Room( 'Kitchen',       (2,2) )

    # Setup East / West connections
    connect_rooms_ew(study, hall)
    connect_rooms_ew(hall, lounge)
    connect_rooms_ew(library, billiard)
    connect_rooms_ew(billiard, dining)
    connect_rooms_ew(conserv, ball)
    connect_rooms_ew(ball, kitchen)
    

    # Setup North / South connections
    connect_rooms_ns(study, library)
    connect_rooms_ns(hall, billiard)
    connect_rooms_ns(lounge, dining)
    connect_rooms_ns(library, conserv)
    connect_rooms_ns(billiard, ball)
    connect_rooms_ns(dining, kitchen)

    #Return one of the rooms, which can be used to access the rest of the mansion
    return study


def connect_rooms(room1, room2, orientation, dir1, dir2):
    h = Hallway(orientation, (dir1, room1), (dir2, room2))

    room1.addHallway(dir2, h)
    room2.addHallway(dir1, h)

def connect_rooms_ew(west_room, east_room):
    connect_rooms(west_room, east_room, 'EW', 'W', 'E')

def connect_rooms_ns(north_room, south_room):
    connect_rooms(north_room, south_room, 'NS', 'N', 'S')


class Location(object):
    def __init__(self):
        self.occupants = set()

    def enter(self, player):
        if player in self.occupants:
            raise Exception('Unable to add player %s to  - already entered' % (player.name, repr(self)))

        self.occupants.add( player )

    def leave(self, player):
        if player not in self.occupants:
            raise Exception( 'Unable to remove player %s from room %s - not entered' % (player.name, repr(self)))

        self.occupants.remove( player )

    def occupantCount(self):
        return len(self.occupants)

class Room(Location):
    valid_directions = set(['N', 'S', 'E', 'W'])
    
    def __init__(self, name, position):
        super(Room, self).__init__()
        self.name = name
        self.hallways = {'N': None,
                         'S': None,
                         'E': None,
                         'W': None }
        self.position = position

    def enterRoom(self, player):
        self.enter(player)

    def leaveRoom(self, player):
        self.leave(player)

    def addHallway(self, direction, hallway):
        if direction in Room.valid_directions:
            self.hallways[ direction ] = hallway
        else:
            raise Exception( 'Invalid hallway direction: %s' % str(direction))

    def __repr__(self):
        return 'The %s' % self.name

class Hallway(Location):
    valid_orientations = set(['EW', 'NS'])
    valid_directions = { 'EW' : set(['E','W']),
                         'NS' : set(['N','S']) }

    def __init__(self, orientation, (direction1, room1), (direction2, room2)):
        super(Hallway, self).__init__()
        self.rooms = {'EW' : {'E': None,
                              'W': None },
                      'NS' : {'N': None,
                              'S': None }}
        
        if orientation in Hallway.valid_orientations:
            self.orientation = orientation
        else:
            raise Exception( 'Invalid Orientation: %s' % repr(orientation) )
        
        self.addRoom(direction1, room1)
        self.addRoom(direction2, room2)

    def dirValid(self, direction):
        return direction in Hallway.valid_directions[ self.orientation ]

    def isConnected(self, direction):
        return self.rooms[ self.orientation ][ direction ] is not None
            
    def addRoom(self, direction, room): 
        if self.dirValid(direction) and not self.isConnected(direction):
            self.rooms[ self.orientation ][ direction ] = room
        else:
            raise Exception( 'Invalid direction, or room already exists at direction: %s - %s' % (repr(direction), repr(room)))

    def enterHallway(self, player):

        # NOTE: Hard-coding maximum hallway entrants to 1
        if self.occupantCount() >= 1:
            raise Exception( 'Maximum occupants exceeded for %s - current occupants: %s' % (self.name, repr(self)))
        self.enter(player)

    def leaveHallway(self,player):
        self.leave(player)

    

    def __repr__(self):
        rooms = self.rooms[ self.orientation ]
        valid_directions = Hallway.valid_directions[ self.orientation ]
        (r1, r2) = (rooms[r] for r in valid_directions)
        return 'The hallway between %s and %s' % (repr(r1), (repr(r2)))



        
class cluelessServer(object):

    def __init__(self, players):
        self.players = players
        self.turns = 0;

    def playGame():
        pass
        

class cluelessClient(object):

    def __init__(self):
        pass


def main():
    pass

if __name__ == '__main__':
    main()
